package cn.nawang.ebeim.server.transport;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.nawang.ebeim.server.constants.Config;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.traffic.ChannelTrafficShapingHandler;

public class HttpUploadServer implements Runnable{
  // 设置6秒检测chanel是否接受过心跳数据
  private static final int READ_WAIT_SECONDS = 6;
  private static final Logger LOG = LoggerFactory.getLogger(HttpUploadServer.class);


  public void start(int port) throws Exception {
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
      ServerBootstrap b = new ServerBootstrap();
      b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
              ch.pipeline().addLast(new HttpResponseEncoder());
              ch.pipeline().addLast(new HttpRequestDecoder());
              ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
              ch.pipeline().addLast("GLOBAL_TRAFFIC_SHAPING", new ChannelTrafficShapingHandler(
                  Config.WRITE_LIMIT, Config.READ_LIMIT, Config.CHECK_INTERVAL));
              ch.pipeline()
                  .addLast(new IdleStateHandler(READ_WAIT_SECONDS, 0, 0, TimeUnit.SECONDS));
              ch.pipeline().addLast(new HttpUploadServerInboundHandler());
            }
          }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
      ChannelFuture f = b.bind(port).sync();
      LOG.info("打开浏览器，输入： " + ("http") + "://127.0.0.1:" + port + '/');
      f.channel().closeFuture().sync();
    } finally {
      workerGroup.shutdownGracefully();
      bossGroup.shutdownGracefully();
    }
  }

  @Override
  public void run() {
    try {
      start(Config.UPLOAD_PORT);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}
